package lion.formail.reader.reader.v5;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import lion.dev.io.FileUtil;
import lion.formail.reader.obj.Idx;
import lion.formail.reader.obj.Index;
import lion.formail.reader.reader.IReader;
import lion.formail.reader.reader.v4.IndReader;

/**
 * foxmail version under 6
 * 
 * @author lion
 * @email hl_0074@sina.com
 * @date 2014年4月29日
 */
public class IndxReader extends IndReader implements IReader {

	@Override
	public int countEmls(boolean countDeleted, File file) throws IOException {

		if (!file.getName().toLowerCase().endsWith("indx")) { throw new IllegalArgumentException(
				"the file must be foxmail's 'indx' file and the filename should be end with 'INDX'"); }
		// 头部64字节
		int header = 0x40;
		int count = 0;
		// 512为一个索引内容
		byte[] content = new byte[0x200];
		DataInputStream dis = null;
		try {
			dis = new DataInputStream(new FileInputStream(file));
			dis.skip(header);
			while ((dis.read(content) != -1)) {
				if (content[0x04] == 0 || (content[0x04] == 1 && countDeleted)) {
					count++;
				}
			}
		} catch (IOException e) {
			throw e;
		} finally {
			if (dis != null) {
				dis.close();
			}
		}
		return count;

	}

	@Override
	public List<Idx> getIndexList(boolean countDeleted, File file) throws IOException {

		if (!file.getName().toLowerCase().endsWith("indx")) { throw new IllegalArgumentException(
				"the file must be foxmail's 'indx' file and the filename should be end with 'INDX'"); }
		// 头部64字节
		int header = 0x40;
		List<Idx> indexList = new ArrayList<Idx>();
		// 每个索引大小为512字节
		byte[] content = new byte[0x200];// 512字节
		DataInputStream dis = null;

		try {

			dis = new DataInputStream(new FileInputStream(file));

			// 跳过头部
			dis.skip(header);

			while (dis.read(content) != -1) {
				if (content[0x04] == 1 && !countDeleted) {
					continue;
				}

				// 读取内容
				Index index = getIndexInfoFromByteArray(content);

				indexList.add(index);
			}
		} catch (IOException e) {
			throw e;
		} finally {
			if (dis != null) {
				dis.close();
			}
		}
		return indexList;
	}

	@Override
	public Index getIndexInfoFromByteArray(byte[] content) {

		Index index = new Index();

		// 基本信息
		fillBasicData(content, index);

		/**
		 * 收信日期 0x14 -0x1b 未取到， <br>
		 * 1,主要是Delphi的时间与Java的时间之间的转换。<br>
		 * 2,Foxmail中以8个字节表示时间，这8个字节如何转换为Delphi的时间
		 */

		// 从0x29开始，以空格为间隔，每一个段为一个信息,段之间以 0 分隔
		// 0x29 sender
		int offset = 0x29;
		byte[] buf = new byte[0x80]; // 128b
		int i = 0;
		i = fillByteArray(content, offset, buf);
		offset += i;
		index.setSender(new String(buf, 0, i));

		// sender's eml
		buf = new byte[0x80];
		offset++;
		i = fillByteArray(content, offset, buf);
		offset += i;
		index.setSenderEML(new String(buf, 0, i));

		// reciver
		buf = new byte[0x80];
		offset++;
		i = fillByteArray(content, offset, buf);
		offset += i;
		index.setReciver(new String(buf, 0, i));

		// reciver's eml
		buf = new byte[0x80];
		offset++;
		i = fillByteArray(content, offset, buf);
		offset += i;
		index.setReciverEML(new String(buf, 0, i));

		// subject
		buf = new byte[0x200 - offset];
		offset++;
		i = fillByteArray(content, offset, buf); // 出错
		offset += i;

		index.setSubject(FileUtil.read(Arrays.copyOfRange(buf, 0, i + 1)));

		return index;
	}

	public byte[] getEmlContent(Index index, File boxFile) throws IOException {

		if (!boxFile.exists()) { throw new FileNotFoundException(boxFile.getAbsolutePath() + " is not found"); }
		if (!boxFile.getName().toLowerCase().endsWith("box")) { throw new IllegalArgumentException(
				"the file must be foxmail's 'box' file and the filename should be end with 'box'"); }
		byte[] content = new byte[index.getSize()];
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(boxFile);
			fis.skip(index.getOffSet());
			fis.read(content);
		} catch (IOException ex) {
			throw ex;
		} finally {
			if (fis != null) {
				fis.close();
			}
		}
		return content;
	}
}